//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#if _MSC_VER > 1000
#pragma once
#endif

#ifndef __PROTOCOL_H__
#define __PROTOCOL_H__

#include <elasys_server.h>
#include <aura.h>

#define MAX_SERVICE_NAME  256
#define MAX_PATH 256

struct request_header
{
    int reqNum;
};

struct reply_header
{
    int error;
};

struct request_max_size
{
    int pad[16];
};

struct test_request
{
    struct request_header __header;
    int val;
};
struct test_reply
{
    struct reply_header __header;
    int val;
};

struct register_request
{
    struct request_header __header;
    ProcessId processId;
    EMuid clsid;
    EIID   iid;
    UInt32 uIndex;
};
struct register_reply
{
    struct reply_header __header;
    oid_t oid;
};

struct unregister_request
{
    struct request_header __header;
    ProcessId processId;
    oid_t oid;
};
struct unregister_reply
{
    struct reply_header __header;
};

struct register_common_request
{
    struct request_header __header;
//    WString name;           :VARARG
    ProcessId processId;
    EMuid clsid;
    EIID   iid;
    UInt32 uIndex;
};
struct register_common_reply
{
    struct reply_header __header;
    oid_t oid;
};

struct unregister_common_request
{
    struct request_header __header;
    ProcessId processId;
//    WString name;            :VARARG
};
struct unregister_common_reply
{
    struct reply_header __header;
};

struct resolve_common_request
{
    struct request_header __header;
//    WString name;            :VARARG
};
struct resolve_common_reply
{
    struct reply_header __header;
    ProcessId processId;
    Int32 type;
    oid_t oid;
    EMuid clsid;
    UInt32 uIndex;
};

struct get_process_id_request
{
    struct request_header __header;
    oid_t oid;
};
struct get_process_id_reply
{
    struct reply_header __header;
    ProcessId processId;
};

struct register_service_request
{
    struct request_header __header;
//    WString name;            :VARARG
    ProcessId processId;
    oid_t oid;
};
struct register_service_reply
{
    struct reply_header __header;
};

struct wait_service_request
{
    struct request_header __header;
//    WString name;            :VARARG
    Millisecond32 msTimeout;
};
struct wait_service_reply
{
    struct reply_header __header;
    WaitResult result;
};

struct attach_service_request
{
    struct request_header __header;
    ProcessId processId;
    oid_t oid;
};
struct attach_service_reply
{
    struct reply_header __header;
};

struct detach_service_request
{
    struct request_header __header;
    ProcessId processId;
    oid_t oid;
};
struct detach_service_reply
{
    struct reply_header __header;
};

struct create_gprocess_request
{
    struct request_header __header;
    ProcessId processId;
};

struct create_gprocess_reply
{
    struct reply_header __header;
};

struct start_process_request
{
    struct request_header __header;
    ProcessId requestPid;
    ThreadPriorityRank priorityRank;
    Int32 capacity;
    // WString name;            :VARARG
    // WString arg;               :VARARG
};
struct start_process_reply
{
    struct reply_header __header;
    ProcessId processId;
};

struct kill_process_request
{
    struct request_header __header;
    ProcessId processId;
    ExitCode exitCode;
};

struct kill_process_reply
{
    struct request_header __header;
};

struct waitfor_process_toexit_request
{
    struct request_header __header;
    ProcessId processId;
    Millisecond32 timeOut;
};

struct waitfor_process_toexit_reply
{
    struct reply_header __header;
    WaitResult waitResult;
};

struct process_IsAlive_request
{
    struct request_header __header;
    ProcessId processId;
};

struct process_IsAlive_reply
{
    struct reply_header __header;
    Boolean bIsAlive;
};

struct release_process_request
{
    struct request_header __header;
    ProcessId requestPid;
    ProcessId processId;
};
struct release_process_reply
{
    struct reply_header __header;
};

struct get_process_startInfo_request
{
    struct request_header __header;
    ProcessId processId;
};
struct get_process_startInfo_reply
{
    struct reply_header __header;
    // WStringBuf name;            :VARARG
    // WStringBuf arg;               :VARARG
};

struct get_process_exitCode_request
{
    struct request_header __header;
    ProcessId processId;
};
struct get_process_exitCode_reply
{
    struct reply_header __header;
    ExitCode exitCode;
};

struct get_process_startTime_request
{
    struct request_header __header;
    ProcessId processId;
};
struct get_process_startTime_reply
{
    struct reply_header __header;
    SystemTime time;
};

struct get_process_exitTime_request
{
    struct request_header __header;
    ProcessId processId;
};
struct get_process_exitTime_reply
{
    struct reply_header __header;
    SystemTime time;
};

struct get_process_processorTimes_request
{
    struct request_header __header;
    ProcessId processId;
};

struct get_process_processorTimes_reply
{
    struct reply_header __header;
    Millisecond32 userTime;
    Millisecond32 privilegedTime;
};

struct addref_thread_request
{
    struct request_header __header;
    ProcessId requestPid;  // who refer the thread;
    ThreadId threadId;
    ProcessId hostPid;     // who host the thread;
};

struct addref_thread_reply
{
    struct reply_header __header;
};

struct get_thread_quitCode_request
{
    struct request_header __header;
    ThreadId threadId;
};
struct get_thread_quitCode_reply
{
    struct reply_header __header;
    QuitCode quitCode;
};

struct get_thread_startTime_request
{
    struct request_header __header;
    ThreadId threadId;
};
struct get_thread_startTime_reply
{
    struct reply_header __header;
    SystemTime time;
};

struct get_thread_quitTime_request
{
    struct request_header __header;
    ThreadId threadId;
};

struct get_thread_quitTime_reply
{
    struct reply_header __header;
    SystemTime time;
};

struct get_thread_name_request
{
    struct request_header __header;
    ThreadId threadId;
};

struct get_thread_name_reply
{
    struct reply_header __header;
};

struct release_thread_request
{
    struct request_header __header;
    ProcessId requestPid;   // who release the thread;
    ThreadId threadId;
};
struct release_thread_reply
{
    struct reply_header __header;
};

struct transfer_thread_info_request
{
    struct request_header __header;
    ProcessId processId;   // who hosted the thread.
    ThreadId threadId;
    QuitCode quitCode;
    SystemTime startTime;
    SystemTime quitTime;
};

struct transfer_thread_info_reply
{
    struct reply_header __header;
};

struct transfer_process_info_request
{
    struct request_header __header;
    ProcessId processId;
    ExitCode exitCode;
    Millisecond32 userTime;
    Millisecond32 privilegedTime;
};
struct transfer_process_info_reply
{
    struct reply_header __header;
};

// -------------------------------------
struct create_enumerator_request
{
    struct request_header __header;
    ProcessId requestPid;   // who create the enumerator.
};

struct create_enumerator_reply
{
    struct reply_header __header;
    Int32 enumeratorId;
};

struct release_enumerator_request
{
    struct request_header __header;
    ProcessId requestPid;
    Int32 enumeratorId;
};

struct release_enumerator_reply
{
    struct reply_header __header;
};

struct get_current_request
{
    struct request_header __header;
    ProcessId requestPid;  // who will refer the process.
    Int32 enumeratorId;
};

struct get_current_reply
{
    struct reply_header __header;
    ProcessId processId;
};

struct move_next_request
{
    struct request_header __header;
    Int32 enumeratorId;
};

struct move_next_reply
{
    struct reply_header __header;
    Boolean bSucceeded;
};

struct reset_enumerator_request
{
    struct request_header __header;
    Int32 enumeratorId;
};

struct reset_enumerator_reply
{
    struct reply_header __header;
};

// --------named mutex ------------
struct create_namedMutex_request
{
    struct request_header __header;
    ProcessId requestPid;  // who will refer the named mutex.
};

struct create_namedMutex_reply
{
    struct reply_header __header;
    Boolean bAlreadyExisted;
    oid_t oid;
};


// ------ named event ------------
struct create_namedEvent_request
{
    struct request_header __header;
    ProcessId requestPid;  // who will refer the named event.
    Boolean bManualReset;
    EventState initialState;
};

struct create_namedEvent_reply
{
    struct reply_header __header;
    Boolean bAlreadyExisted;
    oid_t oid;
};

struct trywait_namedEvent_request
{
    struct request_header __header;
    oid_t oid;
    Millisecond32 msTimeOut;
};

struct trywait_namedEvent_reply
{
    struct reply_header __header;
    WaitResult result;
    EventState state;
};

struct notify_namedEvent_request
{
    struct request_header __header;
    oid_t oid;
    EventState state;
};

struct notify_namedEvent_reply
{
    struct reply_header __header;
};

struct clear_namedEvent_request
{
    struct request_header __header;
    oid_t oid;
};

struct clear_namedEvent_reply
{
    struct reply_header __header;
};

struct condition_create_request
{
    struct request_header __header;
    ProcessId requestPid;  // who will refer the named event.
};

struct condition_create_reply
{
    struct reply_header __header;
    Boolean bAlreadyExisted;
    oid_t oid;
};

struct condition_wait_request
{
    struct request_header __header;
    oid_t oid;
    Millisecond32 msTimeOut;
};

struct condition_wait_reply
{
    struct reply_header __header;
    WaitResult result;
};

struct condition_pulse_request
{
    struct request_header __header;
    oid_t oid;
};

struct condition_pulse_reply
{
    struct reply_header __header;
};

struct condition_pulseall_request
{
    struct request_header __header;
    oid_t oid;
};

struct condition_pulseall_reply
{
    struct reply_header __header;
};

struct create_sharedmemory_request
{
    struct request_header __header;
    ProcessId requestPid;    // who will refer the shared memory.
    MemorySize memorySize;
    Boolean bCommit;
};

struct create_sharedmemory_reply
{
    struct reply_header __header;
    Boolean bAlreadyExisted;
    oid_t oid;
};

struct addref_namedobject_request
{
    struct request_header __header;
    ProcessId requestPid;  // who will refer the named object.
    oid_t oid;
};

struct addref_namedobject_reply
{
    struct reply_header __header;
};

struct release_namedobject_request
{
    struct request_header __header;
    ProcessId requestPid;  // who needs to release the named object.
    oid_t oid;
};

struct release_namedobject_reply
{
    struct reply_header __header;
};

#define REQUEST_TABLE \
    REQUEST_ENTRY(test) \
    REQUEST_ENTRY(register) \
    REQUEST_ENTRY(unregister) \
    REQUEST_ENTRY(register_common) \
    REQUEST_ENTRY(unregister_common) \
    REQUEST_ENTRY(resolve_common) \
    REQUEST_ENTRY(get_process_id) \
    REQUEST_ENTRY(register_service) \
    REQUEST_ENTRY(wait_service) \
    REQUEST_ENTRY(attach_service) \
    REQUEST_ENTRY(detach_service) \
    REQUEST_ENTRY(create_gprocess) \
    REQUEST_ENTRY(start_process) \
    REQUEST_ENTRY(kill_process) \
    REQUEST_ENTRY(waitfor_process_toexit) \
    REQUEST_ENTRY(process_IsAlive) \
    REQUEST_ENTRY(release_process) \
    REQUEST_ENTRY(get_process_startInfo) \
    REQUEST_ENTRY(get_process_exitCode) \
    REQUEST_ENTRY(get_process_startTime) \
    REQUEST_ENTRY(get_process_exitTime) \
    REQUEST_ENTRY(get_process_processorTimes) \
    REQUEST_ENTRY(get_thread_name) \
    REQUEST_ENTRY(addref_thread) \
    REQUEST_ENTRY(get_thread_quitCode)  \
    REQUEST_ENTRY(get_thread_startTime) \
    REQUEST_ENTRY(get_thread_quitTime) \
    REQUEST_ENTRY(release_thread)      \
    REQUEST_ENTRY(transfer_thread_info)  \
    REQUEST_ENTRY(transfer_process_info) \
    REQUEST_ENTRY(create_enumerator)  \
    REQUEST_ENTRY(release_enumerator) \
    REQUEST_ENTRY(get_current)        \
    REQUEST_ENTRY(move_next)          \
    REQUEST_ENTRY(reset_enumerator)   \
    REQUEST_ENTRY(create_namedMutex)  \
    REQUEST_ENTRY(create_namedEvent)  \
    REQUEST_ENTRY(trywait_namedEvent) \
    REQUEST_ENTRY(notify_namedEvent)  \
    REQUEST_ENTRY(clear_namedEvent)   \
    REQUEST_ENTRY(condition_create)   \
    REQUEST_ENTRY(condition_wait)     \
    REQUEST_ENTRY(condition_pulse)    \
    REQUEST_ENTRY(condition_pulseall) \
    REQUEST_ENTRY(create_sharedmemory) \
    REQUEST_ENTRY(addref_namedobject) \
    REQUEST_ENTRY(release_namedobject) \


enum request
{
#define REQUEST_ENTRY(x) REQ_##x,
    REQUEST_TABLE
#undef REQUEST_ENTRY

    REQ_MAX_REQUESTS
};

union generic_request
{
    struct request_max_size max_size;
    struct request_header request_header;
#define REQUEST_ENTRY(x) \
    struct x##_request  x##_request;
    REQUEST_TABLE
#undef REQUEST_ENTRY
};

union generic_reply
{
    struct request_max_size max_size;
    struct reply_header reply_header;
#define REQUEST_ENTRY(x) \
    struct x##_reply  x##_reply;
    REQUEST_TABLE
#undef REQUEST_ENTRY
};

// Server communication

struct central_iovec
{
    void  *ptr;
    unsigned int size;
};

#define IOVEC_MAX_DATA 2

struct central_request_info
{
    union
    {
        union generic_request request;
        union generic_reply reply;
    } u;
    unsigned int request_data_count;                        // count of request data pointers
    struct central_iovec request_data[IOVEC_MAX_DATA];      // request variable size data
    unsigned int reply_data_count;                          // count of reply data pointers
    struct central_iovec reply_data[IOVEC_MAX_DATA];        // reply variable size data
};

#endif /*__PROTOCOL_H__*/
